﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MP3SharpFix
{
    class BitStreamClean : MP3Sharp.Decoding.IBitstream
    {
        public BitStreamClean(byte[] data)
        {
            this.data = data;
            this.dwordOffset = 0;
            this.bitOffset = 0;
        }
        public byte[] data;
        public int dwordOffset;
        public int bitOffset;
        //0 
        //1 2 3 4 5 6 7 8
        //9 .. 16
        //17 .. 24
        static readonly int[] limitmask = { 0,
            0x01, 0x03, 0x07, 0x0f,   0x1f ,0x3f,0x7f,0xff,
            0x01ff, 0x03ff, 0x07ff, 0x0fff,   0x1fff ,0x3fff,0x7fff,0xffff,
            0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,   0x1fffff ,0x3fffff,0x7fffff,0xffffff,
            0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,   0x1fffffff ,0x3fffffff,0x7fffffff,unchecked((int)0xffffffff)
        };

        public int GetBitsFromBuffer(int countBits)
        {
            if (countBits == 0)
                return 0;
            if (countBits > 32 || countBits < 0)
                throw new Exception("error");

            unsafe
            {
                int value = 0;
                fixed (byte* bdata = data)
                {

                    var bitlen = 32 - bitOffset;
                    if (countBits >= bitlen)//读一个bitlen到这个dword结束
                    {
                        var word = bdata[dwordOffset * 4 + 0] << 24 |
                                   bdata[dwordOffset * 4 + 1] << 16 |
                                   bdata[dwordOffset * 4 + 2] << 8 |
                                   bdata[dwordOffset * 4 + 3];
                        var v = word & limitmask[bitlen];//左侧截断
                        value = v << (countBits - bitlen);
                        countBits -= bitlen;
                        dwordOffset++;
                        bitOffset = 0;
                    }
                    if (countBits > 0)//还有,读一点
                    {
                        var word = bdata[dwordOffset * 4 + 0] << 24 |
                                   bdata[dwordOffset * 4 + 1] << 16 |
                                   bdata[dwordOffset * 4 + 2] << 8 |
                                   bdata[dwordOffset * 4 + 3];
                        var v = word;// & limitmask[32 - bitOffset];
                        v >>= (32 - bitOffset - countBits); //右移，右边就没了
                        value += v & limitmask[countBits]; //再限制一下左边
                        bitOffset += countBits;
                    }
                }
                return value;
            }
        }
    }
}
